package com.xc.quickstart.common.filter;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.time.Duration;
import java.time.Instant;
import java.util.Date;

import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;

@Activate(group = {CONSUMER, PROVIDER})
@Slf4j
public class LogDubboFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Instant begin = new Date().toInstant();
        log.debug("[LogDubboFilter]开始：InterfaceName={},MethodName={},Parameter={}",
                invocation.getInvoker().getInterface().getName(),
                invocation.getMethodName(),
                invocation.getArguments());

        Result result = invoker.invoke(invocation);
        Instant end = new Date().toInstant();

        if (result.hasException()) {
            log.error("[LogDubboFilter]异常：InterfaceName={},MethodName={},Parameter={},ex:{}"
                    , invocation.getInvoker().getInterface().getName()
                    , invocation.getMethodName()
                    , invocation.getArguments()
                    , ExceptionUtil.stacktraceToString(result.getException()));
            return result;
        }

        log.info("[LogDubboFilter]结束：InterfaceName={},MethodName={},Parameter={},response:{},cost:{},speed:{}"
                , invocation.getInvoker().getInterface().getName()
                , invocation.getMethodName()
                , invocation.getArguments()
                , JSON.toJSONString(result.getValue())
                , Duration.between(begin, end).toMillis()
                , Duration.between(begin, end).toMillis() > 500 ? "<<slow>>" : "<<fast>>");

        return result;
    }
}


